package com.zhangmeng.tools.controller;

import com.zhangmeng.tools.utils.ImagePath;
import com.zhangmeng.tools.utils.ResourcesUtils;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Callback;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.Arrays;

/**
 * @author : 芊芊墨客
 * @version : 1.0
 * @date : 2023-03-10 11:25
 */
@Slf4j
public class ServerToolsController {

    private SimpleDoubleProperty width = new SimpleDoubleProperty(0.0);
    private SimpleDoubleProperty height = new SimpleDoubleProperty(0.0);
    private AnchorPane root;
    private AnchorPane httpServer;
    private AnchorPane ftpServer;
    private AnchorPane sshClient;
    private AnchorPane socketServer;
    private AnchorPane socket_client_aio;
    private AnchorPane socket_client_nio;
    private AnchorPane socket_server_aio;
    private AnchorPane socket_server_nio;
    private AnchorPane web_socket_client;


    public static final String color_cell = "#f4f4f4";

    @FXML
    private ListView<ResourcesUtils.ServerTools> listView;

    @FXML
    private SplitPane splitPane;

    @FXML
    public void date_query_menu_item(){
        load_small_tools(5);
    }

    @FXML
    public void cron_menu_item(){
        load_small_tools(6);
    }

    @FXML
    public void md5_menu_item() {
        load_encrypt(0);
    }

    @FXML
    public void spring_security_menu_item() {
        load_encrypt(1);
    }

    @FXML
    public void video_menu_item() {
        load_player(0);
    }

    @FXML
    public void music_menu_item() {
        load_player(1);
    }

    @FXML
    public void vip_parser_menu_item() {
        load_player(2);
    }

    @FXML
    public void hex_16(){
        load_small_tools(0);
    }

    @FXML
    private void hex_16_menu_item(){
        load_small_tools(0);
    }

    @FXML
    private void unicode_menu_item(){
        load_small_tools(1);
    }

    @FXML
    private void jwt_menu_item(){
        load_small_tools(2);
    }

    @FXML
    private void color_choose_menu_item(){
        load_small_tools(3);
    }

    @FXML
    public void qr_code_menu_item(){
        load_small_tools(4);
    }

    @FXML
    public void base_62_menu_item(){
        load_codec_tools(0);
    }

    @FXML
    public void base_64_menu_item(){
        load_codec_tools(1);
    }

    @FXML
    public void base_32_menu_item(){
        load_codec_tools(2);
    }

    @FXML
    public void morse_coder_menu_item(){
        load_codec_tools(3);
    }

    @FXML
    private void sql_code_gen_menu_item(){
        load_sql_tools(0);
    }

    @FXML
    public void netty_client_menu_item(){
        load_network_tools(0);
    }

    public void load_encrypt(int index) {

        Stage stage = (Stage) splitPane.getScene().getWindow();

        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("home"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Scene scene = new Scene(fx);
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void load_network_tools(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("network-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void load_sql_tools(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("sql-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void load_codec_tools(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("codec-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void load_small_tools(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("small-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void load_player(int index) {
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("player"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    @FXML
    public void initialize() {
        init();
        listView.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                boolean flag = false;

                if (newValue.getIndex() == 0) {
                    if (httpServer != null){
                        flag = true;
                    }
                    httpServer(flag);
                }
                if (newValue.getIndex() == 1) {
                    if (ftpServer != null){
                        flag = true;
                    }
                    ftpServer(flag);
                }
                if (newValue.getIndex() == 2) {
                    if (sshClient != null){
                        flag = true;
                    }
                    sshClient(flag);
                }

                if (newValue.getIndex() == 3){
                    if (socketServer != null){
                        flag = true;
                    }
                    socketServer(flag);
                }

                if (newValue.getIndex() == 4){
                    if (socket_client_aio != null){
                        flag = true;
                    }
                    socket_client_aio(flag);
                }

                if (newValue.getIndex() == 5){
                    if (socket_server_aio != null){
                        flag = true;
                    }
                    socket_server_aio(flag);
                }
                if (newValue.getIndex() == 6){
                    if (socket_server_nio != null){
                        flag = true;
                    }
                    socket_server_nio(flag);
                }

                if (newValue.getIndex() == 7){
                    if (socket_client_nio != null){
                        flag = true;
                    }
                    socket_client_nio(flag);
                }
                if (newValue.getIndex() == 8){
                    if (web_socket_client != null){
                        flag = true;
                    }
                    web_socket_client(flag);
                }
            }
        });
    }

    private void socket_client_nio(boolean flag) {
        listView.getSelectionModel().select(7);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("socket-client-nio"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            socket_client_nio = root;
        }else {
            root = socket_client_nio;
        }
        common_method();
    }

    private void socket_server_nio(boolean flag) {
        listView.getSelectionModel().select(6);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("socket-server-nio"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            socket_server_nio = root;
        }else {
            root = socket_server_nio;
        }
        common_method();
    }

    private void socket_server_aio(boolean flag) {
        listView.getSelectionModel().select(5);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("socket-server-aio"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            socket_server_aio = root;
        }else {
            root = socket_server_aio;
        }
        common_method();
    }

    private void socket_client_aio(boolean flag) {
        listView.getSelectionModel().select(4);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("socket-client-aio"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            socket_client_aio = root;
        }else {
            root = socket_client_aio;
        }
        common_method();
    }

    private void socketServer(boolean flag){
        listView.getSelectionModel().select(3);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("socket-server"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            socketServer = root;
        }else {
            root = socketServer;
        }
        common_method();
    }

    private void sshClient(boolean flag) {
        listView.getSelectionModel().select(2);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("ssh-connection"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            sshClient = root;
        }else {
            root = sshClient;
        }
        common_method();

        WebView webView = (WebView) root.lookup("#ssh_web");
        AnchorPane.setTopAnchor(webView,167.0);
        AnchorPane.setBottomAnchor(webView,37.0);
        AnchorPane.setLeftAnchor(webView,73.0);
        AnchorPane.setRightAnchor(webView,45.0);
    }

    private void ftpServer(boolean flag) {
        listView.getSelectionModel().select(1);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("ftp-server"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            ftpServer = root;
        }else {
            root = ftpServer;
        }
        common_method();
    }

    private void httpServer(boolean flag) {
        listView.getSelectionModel().select(0);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("http-server"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            httpServer = root;
        }else {
            root = httpServer;
        }
        common_method();
    }

    public static Image getImage(ResourcesUtils.ServerTools player){
        return switch (player){
            case  Http_Server -> new Image(ImagePath.path(ImagePath.ImagePathType.MD5));
            case Ftp_Server -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case SSH_Client -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case Socket_Server -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case Socket_client_aio -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case Socket_server_aio -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case Socket_server_nio -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case Socket_client_nio -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
            case Web_Socket_client -> new Image(ImagePath.path(ImagePath.ImagePathType.SPRING_SECURITY));
        };
    }

    public void init() {
        ResourcesUtils.ServerTools[] values = ResourcesUtils.ServerTools.values();
        ObservableList<ResourcesUtils.ServerTools> list = FXCollections.observableArrayList();
        list.addAll(Arrays.asList(values));
        listView.setItems(list);
        listView.setFixedCellSize(40);
        listView.setCellFactory(new Callback<>() {
            private int position;
            @Override
            public ListCell<ResourcesUtils.ServerTools> call(ListView<ResourcesUtils.ServerTools> playerListView) {
                Label label = new Label();
                label.setPrefWidth(200);
                ListCell<ResourcesUtils.ServerTools> listCell = new ListCell<>() {
                    @Override
                    protected void updateItem(ResourcesUtils.ServerTools player, boolean b) {
                        super.updateItem(player, b);
                        if (!b) {
                            HBox hBox = new HBox(25);
                            hBox.setAlignment(Pos.CENTER);
                            label.setText(player.getTitle());
                            label.setTextFill(Paint.valueOf("#000000"));
                            Image im = getImage(player);
                            ImageView iv = new ImageView(im);
                            iv.setPreserveRatio(true);
                            iv.setFitWidth(15);
                            hBox.getChildren().add(iv);

                            hBox.getChildren().add(label);
                            this.setGraphic(hBox);
                        }
                        this.setStyle("-fx-background-color: " + color_cell);
                    }
                };

                listCell.hoverProperty().addListener((observableValue, aBoolean, t1) -> {
                    if (t1 && !label.getText().equals("")) {
                        position = playerListView.getItems().indexOf(label.getText());
                        label.setFont(new Font(16));
                        playerListView.getFocusModel().focus(position);
                        listCell.setStyle("-fx-background-color: #369e7d");
                    } else {
                        label.setPrefHeight(20);
                        label.setFont(new Font(13));
                        listCell.setStyle("-fx-background-color: " + color_cell);
                    }
                });

                return listCell;
            }
        });

        httpServer(false);
    }

    private void common_method() {
        splitPane.getItems().remove(1);
        splitPane.getItems().add(1, root);
        root.widthProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                double width = splitPane.getWidth();
                ServerToolsController.this.width.set(width);
                log.info("home:--->width:{}", width);
            }
        });
        root.heightProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                double height = splitPane.getHeight();
                ServerToolsController.this.height.set(height);
                log.info("home:--->height:{}", height);
            }
        });

        this.width.addListener((observable, oldValue, newValue) -> {
            ServerToolsController.this.root.setPrefWidth(newValue.doubleValue() - listView.getWidth());
        });

        this.height.addListener((observable, oldValue, newValue) -> {
            ServerToolsController.this.root.setPrefHeight(newValue.doubleValue() - listView.getHeight());
        });
    }

    @FXML
    public void http_request_menu_item(ActionEvent event) {
        load_http_tools(0);
    }

    @FXML
    public void http_upload_menu_item(ActionEvent event) {
        load_http_tools(1);
    }

    @FXML
    public void http_download_menu_item(ActionEvent event) {
        load_http_tools(2);
    }

    public void load_http_tools(int index) {
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("http-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    @FXML
    public void mail_menu_item(ActionEvent event) {
        load_small_tools(7);
    }

    @FXML
    public void http_server_menu_item(ActionEvent event) {
        boolean flag = false;
        if (httpServer != null){
            flag = true;
        }
        httpServer(flag);
    }

    @FXML
    public void ftp_server_menu_item(ActionEvent event) {
        boolean flag = false;
        if (ftpServer != null){
            flag = true;
        }
        ftpServer(flag);
    }

    @FXML
    public void ssh_client_menu_item(ActionEvent event) {
        boolean flag = false;
        if (sshClient != null){
            flag = true;
        }
        sshClient(flag);
    }

    @FXML
    public void socket_server_menu_item(ActionEvent event) {
        boolean flag = false;
        if (sshClient != null){
            flag = true;
        }
        socketServer(flag);
    }

    public void telephone_menu_item(ActionEvent event) {
        load_small_tools(8);
    }

    public void mybatis_plus_gen_menu_item(ActionEvent event) {

        load_sql_tools(1);
    }

    public void JsonView_menu_item(ActionEvent event) {
        load_small_tools(9);
    }

    public void maven_jar_install_menu_item(ActionEvent event) {
        load_small_tools(10);
    }

    public void socket_client_aio_menu_item(ActionEvent event) {
        boolean flag = false;
        if (socket_client_aio != null){
            flag =true;
        }
        socket_client_aio(flag);
    }

    public void socket_server_aio_menu_item(ActionEvent event) {
        boolean flag = false;
        if (socket_server_aio != null){
            flag =true;
        }
        socket_server_aio(flag);
    }

    public void socket_server_nio_menu_item(ActionEvent event) {
        boolean flag = false;
        if (socket_server_nio != null){
            flag =true;
        }
        socket_server_nio(flag);
    }

    public void socket_client_nio_menu_item(ActionEvent event) {
        boolean flag = false;
        if (socket_client_nio != null){
            flag =true;
        }
        socket_client_nio(flag);
    }

    public void jks_file_menu_item(ActionEvent event) {
        load_encrypt(2);

    }

    public void music_parser_menu_item(ActionEvent event) {
        load_player(3);
    }

    public void word_ocr_menu_item(ActionEvent event) {
        load_small_tools(11);
    }

    public void bar_code_menu_item(ActionEvent event) {
        load_small_tools(12);
    }

    public void pdf_menu_item(ActionEvent event) {
        load_small_tools(13);
    }

    public void batch_update_file_name_menu_item(ActionEvent event) {
        load_small_tools(14);
    }

    public void capter_screen_menu_item(ActionEvent event) {
        load_small_tools(15);
    }

    public void json_javabean_gen_menu_item(ActionEvent event) {
        load_sql_tools(2);
    }

    public void sql_query_gen_menu_item(ActionEvent event) {
        load_sql_tools(3);
    }

    public void web_socket_client_menu_item(ActionEvent event) {
        boolean flag = false;
        if (web_socket_client != null){
            flag =true;
        }
        web_socket_client(flag);
    }

    private void web_socket_client(boolean flag) {
        listView.getSelectionModel().select(8);
        if (!flag){
            try {
                root = FXMLLoader.load(ResourcesUtils.getResource("websocket-client"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            web_socket_client = root;
        }else {
            root = web_socket_client;
        }
        common_method();
    }

    public void file_edit_menu_item(ActionEvent actionEvent) {
        load_small_tools(16);
    }

    public void layui_form_gen_menu_item(ActionEvent actionEvent) {
        load_small_tools(17);
    }

    public void log_console_menu_item(ActionEvent actionEvent) {
        load_small_tools(18);
    }

    public void edit_plus_code_menu_item(ActionEvent actionEvent) {
        load_small_tools(19);
    }

    public void minio_upload_menu_item(ActionEvent actionEvent) {
        load_small_tools(20);
    }

    public void excel_read_menu_item(ActionEvent actionEvent) {
        load_small_tools(21);
    }

    public void load_server_tools(int index) {
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("server-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }


    public void load_go_tools(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("go-tools"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void json_to_struct_menu_item(ActionEvent actionEvent) {
        load_go_tools(0);
    }

    public void mysql_to_struct_menu_item(ActionEvent actionEvent) {
        load_go_tools(1);
    }

    public void video_transcoder_menu_item(ActionEvent actionEvent) {
        load_player(4);
    }

    public void js_edit_list(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void ace_js_menu_item(ActionEvent actionEvent) {
        js_edit_list(0);
    }

    public void monaco_js_menu_item(ActionEvent actionEvent) {
        js_edit_list(1);
    }

    public void codemirror_js_menu_item(ActionEvent actionEvent) {
        js_edit_list(2);
    }

    public void timeFx_fx_menu_item(ActionEvent actionEvent) {
        js_edit_list(3);
    }

    public void swing_menu_item(ActionEvent actionEvent) {
        js_edit_list(4);
    }

    public void js_edit_list_impl(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("editor-list-impl"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

//        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
//        listView.getSelectionModel().select(index);
    }

    public void ace_menu_item(ActionEvent actionEvent) {
        js_edit_list_impl(0);
    }

    public void load_chat_app(int index){
        AnchorPane fx = null;
        try {
            fx = FXMLLoader.load(ResourcesUtils.getResource("chat-app"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Scene scene = new Scene(fx);
        Stage stage = (Stage) splitPane.getScene().getWindow();
        stage.setScene(scene);

        ListView<ResourcesUtils.Player> listView = (ListView) fx.lookup("#listView");
        listView.getSelectionModel().select(index);
    }

    public void chat_app_menu_item(ActionEvent actionEvent) {
        load_chat_app(0);
    }
}
